package actions;


import java.util.HashMap;

import java.util.Map;



import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import net.solosky.maplefetion.bean.Buddy;
/**
 * 
 * @author cjcj cj.yangjun@gmail.com
 * @date 2011-01-10
 * @modify 2011-01-17
 *
 */
public class ActionFactory {
	
	/**
	 * task executor
	 */
	private ExecutorService  executor=java.util.concurrent.Executors.newFixedThreadPool(50);
	private static ActionFactory instance=new ActionFactory();
	/**
	 * for mutil-user executor
	 */
	private static Map<Buddy,Map<String,Action>> exeMap=new ConcurrentHashMap<Buddy,Map<String,Action>>();
	
	/**
	 * match the cmd and executer the action from pool.
	 * support mutil-command like /t/r on
	 * @param cmd
	 * @return
	 */
	public static String doCommand(Buddy budy,String cmd){
		if(cmd==null||budy==null)return "";
		Map<String,Action> actMap=exeMap.get(budy);
		StringBuffer rs=new StringBuffer();
		if(actMap==null){
			actMap=new HashMap<String,Action>();
			exeMap.put(budy, actMap);
		}
		String cmds[]=cmd.split("/");
		for(int i=1;i<cmds.length;i++){
			Action act=actMap.get(cmd);
			if(act==null){
				String prefix=cmd.substring(0,cmd.indexOf(" "));
				/**
				 * echo Buddy has itself Action and echo Action instance 
				 * just services only one Buddy so that every Action 
				 * don't need to concern who is its owner.
				 */
				act=checkAct(prefix); // if the act is null??
				// return if the command is wrong or unvaluable 
				if(act==null||!act.checkCmd(cmd))return ""; 
				actMap.put(prefix, act);
			}
			
			Future<Object> future=(Future<Object>) instance.executor.submit(act);
			rs.append(future+" ");
			
			
		}
		return rs.toString();
			
		
	}
	/**
	 * the method create echo Action instance by command string
	 * @param pfix
	 * @return
	 */
	private static Action checkAct(String pfix){
		Action act=null;
		String low_pfix=pfix.toLowerCase();
		/**
		 * how to keep and check the name is unique?
		 * S.1:let all action command register and let them know.
		 * S.2:the name and command is the same name.
		 * S.3:????
		 */ 
		if(low_pfix.equals(GoldPriceAct.cmd)){
			act=new GoldPriceAct();	
		}
		else if(low_pfix.equals(LocalWeatherAct.cmd)){
			act=new LocalWeatherAct();
		}else {
			act=new UnknowAct();
		}
		return act;
	}
	public static void shutdown(){
		instance.executor.shutdown();
	}
	
	public static void  main(String args[]){
		//String cmds[]="".split("/");
		
	}
}
